<?php

namespace App\Servers\WebSocket\EventLoop;

use App\Servers\WebSocket\Utils\Factory;
use Psr\Container\ContainerInterface;
use function Swoole\Coroutine\go;
use Swoole\Coroutine as Co;

class BroadCast
{
    public function __construct(protected ContainerInterface $container, protected $ws) {}
    public function loop()
    {
        $channel = $this->container->get(\Swoole\Coroutine\Channel::class);
        $redisPool = $this->container->get(\Swoole\Database\RedisPool::class);
        $ws = $this->ws;
        Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
        Co::create(function () use ($channel, $redisPool, $ws) {

            go(function () use ($channel, $redisPool, $ws) {
                while (true) {
                    $data = $channel->pop(0.1);  // 非阻塞方式获取数据

                    if ($data !== false) {
                        if (isset($data->scope) && $data->scope == 'chat-room' && $data->op == 'list') {
                            $redis = $redisPool->get();
                            $fds = $redis->SMEMBERS('record_room_id:' . $data->data->roomId . ':fds');

                            foreach ($fds as $fd) {
                                if ($ws->isEstablished($fd)) {
                                    $ws->push($fd, Factory::getInstance()->dispatch($data, $this->container, $fd));
                                } else {
                                    $redis->SREM('record_room_id:' . $data->data->roomId . ':fds', $fd);
                                }
                            }

                            $redisPool->put($redis);
                        }
                    }

                    Co::sleep(0.01);
                }
            });
        });
    }
}
